package com.hava.spring_data.service;

import org.apache.ibatis.javassist.bytecode.CodeAttribute;
import org.apache.ibatis.ognl.ObjectElementsAccessor;
import org.apache.ibatis.transaction.Transaction;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

/**
 * Created by yanfa on 2016/10/26.
 */
public class SimpleService {

    private TransactionTemplate transactionTemplate;

    private PlatformTransactionManager transactionManager;

    public SimpleService(PlatformTransactionManager transactionManager) {
        this.transactionManager = transactionManager;
        this.transactionTemplate = new TransactionTemplate(transactionManager);
        // 配置transactionTemplate
        this.transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_UNCOMMITTED);
        this.transactionTemplate.setTimeout(30);
    }

    public SimpleService(PlatformTransactionManager transactionManager,int index){
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setName("SomeTxName");
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

        TransactionStatus status = transactionManager.getTransaction(def);
    }

    public Object someMethod(){
        return transactionTemplate.execute(
                new TransactionCallback<Object>() {
                    public Object doInTransaction(TransactionStatus status){
                        updateOperation1();
                        return resultOfUpdateOperation2();
                    }
                }
        );
    }

    public Object someMethod2(){
        return transactionTemplate.execute(
                new TransactionCallbackWithoutResult() {
                    public void doInTransactionWithoutResult(TransactionStatus status){
                        updateOperation1();
                        updateOperation2();
                    }
                }
        );
    }

    public Object someMethod3(){
        return transactionTemplate.execute(
                new TransactionCallbackWithoutResult() {
                    public void doInTransactionWithoutResult(TransactionStatus status){
                        try {
                            updateOperation1();
                            updateOperation2();
                        }catch (RuntimeException ex) {
                            status.setRollbackOnly();
                        }
                    }
                }
        );
    }

    public void updateOperation1(){}
    public void updateOperation2() {}
    public Object resultOfUpdateOperation2(){return new Object();}

    //PlatformTransactionManager
    public void SomeMethod4(){
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setName("SomeTxName");
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

        TransactionStatus status = this.transactionManager.getTransaction(def);

        try
        {
            updateOperation1();
            updateOperation2();
        }catch (RuntimeException ex) {
            this.transactionManager.rollback(status);
            throw ex;
        }

        this.transactionManager.commit(status);
    }
}
